﻿using System;
using System.Collections.Generic;
using System.Linq;
using nanoCMS.Blog.Concrete;
using nanoCMS.Core;
using nanoCMS.Core.Extensions;

//TODO: dodati da blogpostovi imaju svoj url, taj url mora biti unikatan u svim tenantima kojima blogpost pripada

namespace nanoCMS.Blog.Providers
{
    public class BlogPostProvider
    {
        private readonly WorldContext worldContext;
        private readonly BlogCategoryProvider blogCategoryProvider;
        private BlogEntities _entities;
        private BlogEntities Entities
        {
            get { return _entities ?? (_entities = new BlogEntities(worldContext.EntityConnectionString)); }
        }

        public BlogPostProvider(WorldContext worldContext)
        {
            this.worldContext = worldContext;
            this.blogCategoryProvider = new BlogCategoryProvider(this.worldContext);
        }

        public BlogReturn Add(string title, string summary, string content, bool allowComments, 
            DateTime? publishedFrom, DateTime? publishedTo, bool sticky, string primaryImage, 
            List<int> categories, out BlogPost blogPost)
        {
            blogPost = new BlogPost
            {
                Title = title,
                Summary = summary,
                Content = content.IfNullSet("empty"),
                CreatedBy = SessionManagerBase.CurrentUser.UserID,
                CreatedDate = DateTime.Now,
                CommentsAllowed = allowComments,
                PublishedFrom = publishedFrom,
                PublishedTo = publishedTo
            };

            Entities.BlogPosts.AddObject(blogPost);
            Entities.SaveChanges();

            //Add blog post to category
            foreach (var category in categories)
            {
                blogCategoryProvider.AddBlogPostToCategory(blogPost.BlogPostID, category);
            }
            return BlogReturn.Success;
        }


        /// <summary>
        /// Get posts with given filters
        /// </summary>
        /// <param name="categoryID"></param>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="userID"></param>
        /// <param name="publishedTo"></param>
        /// <param name="tenantID"></param>
        /// <param name="publishedFrom"></param>
        /// <returns></returns>
        public List<BlogPost> GetPosts(int? categoryID = null, int? skip = null, int? take = null, int? userID = null, 
            DateTime? publishedFrom = null, DateTime? publishedTo = null, int? tenantID = null)
        {
            IQueryable<BlogPost> posts = Entities.BlogPosts;
            if (categoryID != null)
                posts = posts.Where(x => x.BlogCategories.Any(y => y.BlogCategoryID == (int)categoryID));

            if (userID != null)
                posts = posts.Where(x => x.CreatedBy == userID);

            //TODO:Not implemented
            if (tenantID != null)
            {

            }

            int count = posts.Count();
            if (skip != null)
            {
                if (skip >= count) return new List<BlogPost>();
                posts = posts.Skip((int)skip);
            }
            if (take != null)
            {

                if (count - skip < take) take = count - skip;
                if (take > 0)
                    posts = posts.Take((int)take);
            }

            posts = posts.OrderByDescending(x => x.CreatedDate);
            return posts.ToList();
        }

        public BlogReturn GetBlogPost(int blogID, out BlogPost blogPost)
        {
            blogPost = Entities.BlogPosts.SingleOrDefault(x => x.BlogPostID == blogID);
            return blogPost != null ? BlogReturn.Success : BlogReturn.EntityNotFound;
        }

        public BlogReturn Edit(int blogPostID, string title, string summary, string content, bool allowComments, 
            DateTime? publishedFrom, DateTime? publishedTo, bool sticky, string primaryImage, 
            List<int> categories, out BlogPost blogPost)
        {
            if (GetBlogPost(blogPostID, out blogPost) != BlogReturn.Success)
            {
                return BlogReturn.EntityNotFound;
            }
            blogPost.Title = title;
            blogPost.Summary = summary;
            blogPost.Content = content.IfNullSet("null");
            blogPost.CommentsAllowed = allowComments;
            blogPost.Sticky = sticky;
            blogPost.PrimaryImage = primaryImage;
            Entities.SaveChanges();
            return BlogReturn.Success;
        }
    }
}
